
#include <QTimer>

#include "single.h"


Single::Single(QWidget *parent) : Board(parent)
{
    //设置电脑计算步数
    level = 4 ;
}

Single::~Single()
{

}



void Single::player_move(QPoint p)
{
    if(this->move_side)
    {
        Board::player_move(p);
    }
    if(!this->move_side)
    {
        QTimer::singleShot(100, this, SLOT(computer_move()));
        //computer_move();
    }

}

void Single::computer_move()
{
    Step *step = best_move();
    step_move(step);
    delete step;
    update();
    win_fail();
}

void Single::all_move(QVector<Step *> &steps)
{
    //双方棋子id范围
    int side_min = 0, side_max = 16;
    if(this->move_side)
    {
        side_min = 16;
        side_max = 32;
    }

    for(int i = side_min; i < side_max; i++)
    {
        //棋子被吃就不用计算
        if(!board_stones[i].stone_life)
        {
            continue;
        }
        //在棋盘上搜索所有可能的走法
        for(int x = 0; x < 9; x++)
        {
            for(int y = 0; y < 10; y++)
            {
                int id = xy_id(x, y);
                if(id != -1 && board_stones[i].stone_side == board_stones[id].stone_side)
                {
                    continue;
                }
                this->move_id = i;
                if(can_move(x, y))
                {
                    int xx,yy;
                    point_xy(point(i), xx, yy);
                    save_step(i, id, xx, yy, x, y, steps);
                }
                this->move_id = -1;
            }
        }
    }
}


int Single::calc_score()
{
    //enum chess_type{jiang, che, ma, pao, shi, xiang, zu};
    //棋子分数
    static int chess_score[] = {250000, 10000, 1000, 1000, 500, 500, 500};
    //双方总分
    int up_score = 0, down_score = 0;
    for(int i = 0; i < 32 ;i++)
    {
        if(!board_stones[i].stone_life)
        {
            continue;
        }
        if(i < 16)
        {
            up_score += chess_score[board_stones[i].stone_type];
        }
        else
        {
            down_score += chess_score[board_stones[i].stone_type];
        }
    }
    //分差
    return up_score - down_score;
}


void Single::step_move(Step *step)
{
    //吃棋
    if(step->kill_id != -1)
    {
        board_stones[step->kill_id].stone_life = false;
    }
    //走棋
    board_stones[step->move_id].stone_x = step->to_x;
    board_stones[step->move_id].stone_y = step->to_y;
    //交换
    this->move_side = !this->move_side;
}

void Single::step_back(Step *step)
{
    if(step->kill_id != -1)
    {
        board_stones[step->kill_id].stone_life = true;
    }
    board_stones[step->move_id].stone_x = step->from_x;
    board_stones[step->move_id].stone_y = step->from_y;
    //交换
    this->move_side = !this->move_side;
}

int Single::min_score(int lvl_max, int lvl)
{
    if(lvl == 1)
    {
        return calc_score();
    }
    QVector<Step *> steps;
    all_move(steps);
    int min_max = 300000;
    while(steps.count())
    {
        Step *step = steps.last();
        steps.removeLast();
        step_move(step);
        int step_max = max_score(min_max, lvl - 1);
        step_back(step);
        delete step;
        if(step_max <= lvl_max)
        {
            while (steps.count())
            {
                Step *step = steps.last();
                steps.removeLast();
                delete step;
            }
            return step_max;
        }
        if(step_max < min_max)
        {
            min_max = step_max;
        }
    }
    return min_max;
}


int Single::max_score(int lvl_min, int lvl)
{
    if(lvl == 1)
    {
        return calc_score();
    }
    QVector<Step *> steps;
    all_move(steps);
    int max_min = -300000;
    while(steps.count())
    {
        Step *step = steps.last();
        steps.removeLast();
        step_move(step);
        int step_min = min_score(max_min, lvl - 1);
        step_back(step);
        delete step;
        if(step_min >= lvl_min)
        {
            while (steps.count())
            {
                Step *step = steps.last();
                steps.removeLast();
                delete step;
            }
            return step_min;
        }
        if(step_min > max_min)
        {
            max_min = step_min;
        }
    }
    return max_min;
}

Step *Single::best_move()
{
    Step *best = NULL;
    QVector<Step *> steps;
    all_move(steps);
    int max_min = -300000;
    while(steps.count())
    {
        //计算一步的分数
        Step *step = steps.last();
        steps.removeLast();

        step_move(step);
        int step_min = min_score(max_min, this->level);
        step_back(step);

        if(step_min > max_min)
        {
            if(best)
            {
                delete best;
            }
            best = step;
            max_min = step_min;
        }
        else
        {
            delete step;
        }
    }
    return best;
}


